Re-run dep-scan when its parent compile is affected#51
Merged
Conversation
When an already-tracked header is edited to add a #include of a new header (or any change that introduces a new transitive dependency), pup must re-run not only the parent compile but also its sibling dep-scan command (OutputAction::InjectImplicitDeps). Otherwise the dep-scan never sees the new transitive header, never reports it as a discovered dep, and the resulting implicit-dep edge is never recorded in the index. Subsequent edits to the new transitive header then appear invisible to change detection and pup reports "Nothing to do" with a stale .o. Fix: in collect_affected_commands, after the file-cascade walk, attach any command whose parent_command is in the affected set. Dep-scan commands have no graph outputs (they capture stdout, not files), so the existing cascade cannot reach them — they must be tied to their parent explicitly. Converts the [\!shouldfail] reproducer added in d71e75b into a passing regression guard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7103271 to
608d851
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes the transitive implicit-dep tracking bug reported in
pup-header-detection-bug.md(2026-05-15 update) and reproduced by the[\!shouldfail]-tagged SCENARIO landed in d71e75b. This PR makes that SCENARIO turn green and converts it into a permanent regression guard.The bug
When an already-tracked header is edited to
#includea new header (or any change introduces a new transitive dependency), the parent compile re-runs correctly, but the sibling dep-scan command (OutputAction::InjectImplicitDeps) does not. The dep-scan therefore never sees the new transitive header, never reports it as a discovered dep, and the resulting implicit-dep edge is never recorded in the index. Subsequent edits to the new transitive header then appear invisible to change detection — pup reportsNothing to dowith a stale.o.Root cause
collect_affected_commandswalks the build graph forward from changed files viaget_outputs(consumers) andget_order_only_dependents. Dep-scan commands capture stdout rather than producing file outputs, so they have zero graph outputs. The existing cascade therefore cannot reach them, and they never get added to the affected set — no matter how many of their implicit deps changed.Diagnosed with
pup show indexagainst the reproducer fixture:Fix
In
collect_affected_commands, after the file-cascade walk, attach any command whoseparent_commandis in the affected set. The graph already tracks the parent-command linkage on dep-scan nodes (set indep_scanner.cppandrule_pattern.cpp); we just leverage it to bind the dep-scan's dirty status to its parent's.12 lines in
dag.cppplus removing the[\!shouldfail]tag and theCHECK-instead-of-REQUIREworkaround in the regression test.Test plan
test/e2e/fixtures/header_dep_transitive/test.sh) now exits 0 with output:PASS: pup detected transitive header change.pup show index: after step 2,main.c's implicit-dep set now includesinclude/newhdr.h(was missing pre-fix)"Transitive implicit-dep header tracking"passes cleanly (no longer[\!shouldfail])make formatcleanScope note
This fix addresses the "edit existing header to introduce new transitive include" scenario from
pup-header-detection-bug.md. The related scenario indocs/bug-unscoped-build-missing-new-header-dep.md(brand-new src + brand-new header in same build) may be a distinct first-build code path; not addressed here. The current PR is the minimal fix for the reproducer that exists.🤖 Generated with Claude Code